package com.smart.community.commons.config;

import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.util.concurrent.TimeUnit;

/**
 * Caffeine本地内存缓存统一配置类
 * 
 * 功能说明：
 * 1. 使用Caffeine作为本地内存缓存，替代Redis缓存
 * 2. 支持@Cacheable注解，无需修改业务代码
 * 3. 无需序列化/反序列化，直接存储对象引用
 * 4. 解决BigDecimal类型转换、@class类型信息等问题
 * 5. 提供高性能的本地缓存解决方案
 * 6. 支持复杂对象缓存，无需额外配置
 * 7. 统一管理所有模块的缓存配置，避免Bean冲突
 * 
 * 设计理念：
 * - 遵循Spring缓存抽象层的统一管理原则
 * - 通过cacheNames区分不同业务场景
 * - 避免模块化配置带来的复杂性和Bean冲突
 * - 提供灵活而简洁的缓存策略配置
 * 
 * 缓存策略：
 * - 默认过期时间：30分钟
 * - 最大缓存条目：10,000个
 * - 支持特定缓存的个性化配置
 * - 启用统计信息，便于监控和优化
 * 
 * 注意事项：
 * - 本地缓存，不支持分布式部署
 * - 缓存数据随应用重启丢失
 * - 受限于应用所在服务器的内存容量
 * 
 * 遵循规范：
 * - 《Java后端SpringBoot代码开发规范.md》
 * - Spring Cache抽象层最佳实践
 * - 统一配置管理原则
 * 
 * @author Wu.Liang
 * @version 1.0.0 - Caffeine统一缓存配置
 * @since 2025-01-30
 */
@Configuration
@EnableCaching
public class CaffeineCacheConfig {

    /**
     * 配置Caffeine缓存管理器
     * 
     * 功能说明：
     * 1. 作为主缓存管理器，支持所有模块的缓存需求
     * 2. 通过cacheNames区分不同业务场景的缓存
     * 3. 提供统一的缓存策略和配置
     * 4. 支持复杂对象的本地缓存
     * 5. 避免Bean冲突，统一管理所有缓存
     * 
     * 缓存配置策略：
     * - 基础数据缓存：2-4小时（区域、社区、楼栋等，变化频率低）
     * - 业务数据缓存：30分钟-1小时（房户、用户等，变化频率中等）
     * - 统计数据缓存：1小时（统计报表等，变化频率低）
     * - 权限数据缓存：30分钟（用户权限、角色等，变化频率中等）
     * - 实时数据缓存：10-15分钟（维修进度、催缴记录等，变化频率高）
     * 
     * @return CacheManager 缓存管理器实例
     */
    @Bean("cacheManager")
    @Primary
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        
        // 配置缓存全局默认规则
        Caffeine<Object, Object> caffeine = Caffeine.newBuilder()
                .expireAfterWrite(30, TimeUnit.MINUTES) // 默认过期时间30分钟
                .maximumSize(10_000) // 最大缓存条目数
                .recordStats(); // 启用统计信息
        
        cacheManager.setCaffeine(caffeine);
        
        // 注意：Caffeine的setCacheSpecification不支持缓存名称包含冒号的格式
        // 因此我们使用默认配置，所有缓存使用相同的过期时间和容量设置
        // 如果需要为特定缓存设置不同的配置，可以通过编程方式创建多个CacheManager
        
        return cacheManager;
    }
}
